package prometheus

import (
	"github.com/prometheus/client_golang/prometheus"
	"gofire"
	"strconv"
	"time"
)

type MiddlewareBuilder struct {
	Name        string
	Subsystem   string
	ConstLabels map[string]string
	Help        string
}

func (m *MiddlewareBuilder) Build() gofire.Middleware {
	summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
		Subsystem:   m.Subsystem,
		Name:        m.Name,
		Help:        m.Help,
		ConstLabels: m.ConstLabels,
	}, []string{"pattern", "method", "status"})
	// Prometheus 的注册器（Registry）负责存储所有的指标信息。当 Prometheus 服务来抓取数据时，它会从注册器中获取这些指标，并将它们转换为适合网络传输的格式
	prometheus.MustRegister(summaryVec)
	return func(handleFunc gofire.HandleFunc) gofire.HandleFunc {
		return func(ctx *gofire.Context) error {
			startTime := time.Now()
			err := handleFunc(ctx)
			endTime := time.Now()
			go report(endTime.Sub(startTime), ctx, summaryVec)
			return err
		}
	}
}

func report(dur time.Duration, ctx *gofire.Context, vec prometheus.ObserverVec) {
	status := ctx.RespStatusCode
	route := "unknown"
	if ctx.Path() != "" {
		route = ctx.Path()
	}
	ms := dur / time.Millisecond
	vec.WithLabelValues(route, ctx.Method(), strconv.Itoa(status)).Observe(float64(ms))
}
